/* package main

import (
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

// 自定义Claims结构体，用于存储Payload信息
type MyCustomClaims struct {
	UserID int    `json:"id"`
	Name   string `json:"name"`
	jwt.StandardClaims
}

func main() {
	// 创建Gin引擎并注册路由
	r := gin.Default()

	// 用户登录路由
	r.POST("/login", func(c *gin.Context) {
		// 验证用户身份并获取用户信息
		username := c.PostForm("username")
		password := c.PostForm("password")
		if username == "admin" && password == "123456" {
			// 成功登录后创建Token，并将Token返回给客户端
			tokenString, err := createToken(123, "John Doe")
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
				return
			}
			c.Writer.Header().Set("Authorization", "Bearer "+tokenString)
			c.JSON(http.StatusOK, gin.H{"token": tokenString})
		} else {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})
		}
	})

	// 需要Token认证的API路由
	authed := r.Group("/")
	authed.Use(authMiddleware())
	authed.GET("/api/hello", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"message": "Hello, world!"})
	})

	// 启动HTTP服务器
	r.Run(":80")
}

// 创建Token的函数
func createToken(userID int, name string) (string, error) {
	// 创建一个新的签名对象
	token := jwt.New(jwt.SigningMethodHS256)

	// 设置Header和Payload信息
	claims := &MyCustomClaims{
		UserID: userID,
		Name:   name,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Second * 20).Unix(),
			Issuer:    "myapp",
		},
	}
	token.Claims = claims

	// 添加Secret Key并对Token进行签名
	secretKey := []byte("mysecret")
	tokenString, err := token.SignedString(secretKey)
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// Token认证的中间件函数
func authMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {

		// 获取Authorization Header中的Token信息
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Missing Authorization header"})
			return
		}
		tokenString := authHeader[7:]

		// 解析并验证Token
		parsedToken, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
			return []byte("mysecret"), nil
		})
		if err != nil {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
			return
		}
		claims, ok := parsedToken.Claims.(*MyCustomClaims)
		if !ok || !parsedToken.Valid {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
			return
		}
		// 将解析出的用户信息存放在Context中，供后续处理函数使用
		c.Set("user_id", claims.UserID)
		c.Next()
	}
}
*/

package main

import (
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

// 自定义Claims结构体，用于存储Payload信息
type MyCustomClaims struct {
	UserID int    `json:"id"`
	Name   string `json:"name"`
	jwt.StandardClaims
}

func main() {
	// 创建Gin引擎并注册路由
	r := gin.Default()

	// 用户登录路由
	r.POST("/login", func(c *gin.Context) {
		// 验证用户身份并获取用户信息
		username := c.PostForm("username")
		password := c.PostForm("password")
		if username == "admin" && password == "123456" {
			// 成功登录后创建Token，并将Token返回给客户端
			tokenString, err := createToken(123, "admin")
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
				return
			}
			c.SetCookie("Token", tokenString, 20, "/", "", false, false)
			c.JSON(http.StatusOK, gin.H{"token": tokenString})
		} else {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})
		}
	})

	// 需要Token认证的API路由
	authed := r.Group("/")
	authed.Use(authMiddleware())
	authed.GET("/api/hello", func(c *gin.Context) {
		id := c.GetInt("user_id")
		name := c.GetString("user_name")
		message := name + "欢迎回来！"
		c.JSON(http.StatusOK, gin.H{"message": message, "id": id})
	})
	r.Run(":80")
}

// 创建Token的函数
func createToken(userID int, name string) (string, error) {
	// 创建一个新的签名对象
	token := jwt.New(jwt.SigningMethodHS256)
	// 设置Header和Payload信息
	claims := &MyCustomClaims{
		UserID: userID,
		Name:   name,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Second * 10).Unix(),
			Issuer:    "root",
		},
	}
	token.Claims = claims

	// 添加Secret Key并对Token进行签名
	secretKey := []byte("breeze")
	tokenString, err := token.SignedString(secretKey)
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// Token认证的中间件函数
func authMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		authHeader, err := c.Request.Cookie("Token")
		if err != nil {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Missing Authorization header"})
			return
		}
		// 解析并验证Token
		parsedToken, err := jwt.ParseWithClaims(authHeader.Value, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
			return []byte("breeze"), nil
		})
		if err != nil {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
			return
		}
		claims, ok := parsedToken.Claims.(*MyCustomClaims)
		if !ok || !parsedToken.Valid {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
			return
		}
		// 将解析出的用户信息存放在Context中，供后续处理函数使用
		c.Set("user_id", claims.UserID)
		c.Set("user_name", claims.Name)
		c.Next()
	}
}
